﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.Publishing;

namespace SharePointHelper.DLL.SSOM
{
	public class Page
	{
		/// <summary>
		/// Rename publishing page filename
		/// http://sharepoint.stackexchange.com/questions/2064/how-to-rename-a-publishing-page-in-code
		/// </summary>
		/// <param name="page"></param>
		/// <param name="newFilename"></param>
		public static void RenamePage(PublishingPage page, string newFilename, bool isSaveChanges)
		{
			try
			{
				if (page != null && !string.IsNullOrEmpty(newFilename))
				{
					// checkout if required
					if (IsCheckOutRequired(page)) { page.ListItem.File.CheckOut(); }

					// remove .aspx since this gets automatically added later
					if (newFilename.ToLower().Contains(".aspx")) 
					{
						Utilities.ReplaceCaseInsensitive(newFilename, ".aspx", "");
					}

					// set new page filename (.aspx is added automatically)
					page.ListItem["BaseName"] = newFilename;

					if (isSaveChanges)
					{
						if (!SystemSaveAndPublish(page)) { throw new Exception("Failed to save page"); }
					}
				}
			}
			catch (Exception ex)
			{
				string pageName = (page == null) ? null : page.Name;
				Log.WriteError("dtrygfgdrt5drdfdfsdrs", ex, "page name: " + pageName);
			}
		}
		/// <summary>
		/// Get pages colelction from publishing web object
		/// </summary>
		/// <param name="pubWeb"></param>
		/// <param name="q"></param>
		/// <returns></returns>
		public static PublishingPageCollection GetPages(PublishingWeb pubWeb, SPQuery q)
		{
			PublishingPageCollection pages = null;
			try
			{
				// init
				if (pubWeb == null) { throw new Exception("PublishingWeb passed is null"); }
				if (q == null) { q = new SPQuery(); }

				// get pages collection
				pages = pubWeb.GetPublishingPages(q);
			}
			catch (Exception ex)
			{
				Log.WriteError("rufgyufgfseeHHs", ex);
				pages = null;
			}
			return pages;
		}

		/// <summary>
		/// Get pages collection from publishing web
		/// </summary>
		/// <param name="web"></param>
		/// <param name="q"></param>
		/// <returns></returns>
		public static PublishingPageCollection GetPages(SPWeb web, SPQuery q)
		{
			PublishingPageCollection pages = null;
			try
			{
				// init
				if (web == null) { web = Web.GetWeb(); }
				if (web == null) { throw new Exception("SPWeb passed is null or can't get from SPContext"); }
				if (!PublishingWeb.IsPublishingWeb(web)) { throw new Exception("SPWeb passed is not a publishing web: " + web.Title); }


				// 1.) get publishing web
				PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(web);

				// 2.) get pages collection, call original
				pages = GetPages(pubWeb, q);

			}
			catch (Exception ex)
			{
				Log.WriteError("u7i6rtjeshteseeHHs", ex);
				pages = null;
			}
			return pages;
		}

		public static PublishingPageCollection GetPages(PublishingWeb pubWeb)
		{
			return GetPages(pubWeb, null);
		}


		public static PublishingPage GetPageById(PublishingWeb pubWeb, int pageId)
		{
			PublishingPage page = null;
			try
			{
				// init
				if (pubWeb == null) { throw new Exception("Publishing Web passed is null"); }

				page = pubWeb.GetPublishingPage(pageId);
			}
			catch (Exception ex)
			{
				Log.WriteError("8ieewrsrddcxzsed54", ex);
				page = null;
			}
			return page;
		}
		public static PublishingPage GetPageById(SPWeb web, int pageId)
		{
			PublishingPage page = null;
			try
			{
				// init
				if (web == null) { web = Web.GetWeb(); }
				if (web == null) { throw new Exception("SPWeb passed is null or can't get from SPContext"); }
				if (!PublishingWeb.IsPublishingWeb(web)) { throw new Exception("SPWeb passed is not a publishing web: " + web.Title); }


				// 1.) get publishing web
				PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(web);

				// 2.) call original
				page = GetPageById(pubWeb, pageId);
			}
			catch (Exception ex)
			{
				Log.WriteError("8ietuyffgddcxzsed54", ex);
				page = null;
			}
			return page;
		}



		/// <summary>
		/// Get a page from publishing web
		/// Must include url + filename, just in case the file is in a subFolder
		/// IMPORTANT: This member is reserved for internal use and is not intended to be used directly from your code
		/// http://msdn.microsoft.com/en-us/library/ee568681.aspx
		/// </summary>
		/// <param name="pubWeb"></param>
		/// <param name="urlIncludingFilename"></param>
		/// <returns></returns>
		public static PublishingPage GetPageByUrl(PublishingWeb pubWeb, string urlIncludingFilename)
		{
			PublishingPage page = null;
			try
			{
				// init
				if (pubWeb == null) { throw new Exception("Publishing Web passed is null"); }
				if (string.IsNullOrEmpty(urlIncludingFilename)) { throw new Exception("url passed is null"); }
				if (urlIncludingFilename.Substring(urlIncludingFilename.Length - 1, 1) == "/") { throw new Exception("Filename must be included in url"); }
				if (!urlIncludingFilename.Contains(".aspx")) { urlIncludingFilename += ".aspx"; }
				if (!urlIncludingFilename.ToLower().Contains("/pages/"))
				{
					// remove preceeding slash
					if (urlIncludingFilename.Substring(0, 1) == "/") { urlIncludingFilename = urlIncludingFilename.Substring(1); }

					// add pubWeb server relative url
					urlIncludingFilename = pubWeb.Web.ServerRelativeUrl + "/Pages/" + urlIncludingFilename;
					urlIncludingFilename = urlIncludingFilename.Replace("//", "/");	// just in case server relative url contains trailing slash
				}

				page = pubWeb.GetPublishingPage(urlIncludingFilename);
			}
			catch (Exception ex)
			{
				Log.WriteError("tyutdhfsGGdsdsz", ex, "url: " + urlIncludingFilename);
				page = null;
			}
			return page;
		}
		public static PublishingPage GetPageByUrl(SPWeb web, string urlIncludingFilename)
		{
			PublishingPage page = null;
			try
			{
				// 1.) get publishing web
				PublishingWeb pubWeb = Publishing.GetPublishingWeb(web);

				// 2.) call original
				page = GetPageByUrl(pubWeb, urlIncludingFilename);
			}
			catch (Exception ex)
			{
				Log.WriteError("6udfdsfdr5trt6gt", ex);
				page = null;
			}
			return page;
		}


		/// <summary>
		/// Get SPContentType object by passing content type name
		/// </summary>
		/// <param name="pubSite"></param>
		/// <param name="contentTypeName"></param>
		/// <returns></returns>
		public static SPContentType GetContentType(PublishingSite pubSite, string contentTypeName)
		{
			SPContentType contentType = null;
			try
			{
				// init
				if (pubSite == null) { pubSite = Publishing.GetPublishingSite(); }
				if (pubSite == null) { throw new Exception("PublishingSite not passed and failed to get it from SPContext"); }
				if (string.IsNullOrEmpty(contentTypeName)) { throw new Exception("Content type name passed is null"); }

				contentType = pubSite.ContentTypes[contentTypeName];
			}
			catch (Exception ex)
			{
				Log.WriteError("dyrudtshrasddsrrtr", ex, "content type: " + contentTypeName);
				contentType = null;
			}
			return contentType;
		}

		public static SPContentType GetContentType(string contentTypeName)
		{
			return GetContentType(null, contentTypeName);
		}


		/// <summary>
		/// Get all page layouts for passed publishing site
		/// </summary>
		/// <returns></returns>
		public static List<PageLayout> GetPageLayouts(PublishingSite pubSite, SPContentType contentType)
		{
			List<PageLayout> pageLayouts = null;
			try
			{
				// init
				if (pubSite == null) { pubSite = Publishing.GetPublishingSite(); }
				if (pubSite == null) { throw new Exception("Failed to get publishing site from SPContext and param passed was null"); }
				pageLayouts = new List<PageLayout>();


				PageLayoutCollection _pageLayouts = null;
				if (contentType != null) { _pageLayouts = pubSite.GetPageLayouts(contentType, true); }
				if (contentType == null) { _pageLayouts = pubSite.GetPageLayouts(true); }
				if (_pageLayouts == null || _pageLayouts.Count == 0) { throw new Exception("No PageLayouts found in publishing site collection"); }

				foreach (PageLayout pageLayout in _pageLayouts)
				{
					pageLayouts.Add(pageLayout);
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("56utrdsH5dfsdd5tyu", ex);
				pageLayouts = null;
			}
			return pageLayouts;
		}
		/// <summary>
		/// Get all page layouts for passed publishing site
		/// </summary>
		/// <param name="pubSite"></param>
		/// <returns></returns>
		public static List<PageLayout> GetPageLayouts(PublishingSite pubSite)
		{
			// call original
			return GetPageLayouts(pubSite, null);
		}

		/// <summary>
		/// Get Page Layout object (used for creating new pages)
		/// </summary>
		/// <param name="pubSite"></param>
		/// <param name="pageLayoutTitle"></param>
		/// <returns></returns>
		public static PageLayout GetPageLayout(PublishingSite pubSite, string pageLayoutTitle, SPContentType contentType)
		{
			PageLayout pageLayout = null;
			try
			{
				// init
				if (pubSite == null) { pubSite = Publishing.GetPublishingSite(); }
				if (pubSite == null) { throw new Exception("Failed to get publishing site from SPContext and param passed was null"); }
				if (string.IsNullOrEmpty(pageLayoutTitle)) { throw new Exception("PageLayout name passed is null"); }
				pageLayoutTitle = pageLayoutTitle.ToLower();


				// 1.) get all existing layouts
				List<PageLayout> existingLayouts = GetPageLayouts(pubSite, contentType);
				if (existingLayouts == null || existingLayouts.Count == 0) { throw new Exception("No PageLayouts found in publishing site collection"); }

				// 2.) get page layout from collection
				foreach (PageLayout pl in existingLayouts)
				{
					if (pl.Title.ToLower() == pageLayoutTitle)
					{
						pageLayout = pl;
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("6u7ir6e6rwh5gsaes", ex, "page layout name: " + pageLayoutTitle);
				pageLayout = null;
			}
			return pageLayout;
		}

		/// <summary>
		/// Get page layout from passed filename
		/// </summary>
		/// <param name="rootWeb"></param>
		/// <param name="pageLayoutFilename"></param>
		/// <returns></returns>
		public static PageLayout GetPageLayout(PublishingSite pubSite, string pageLayoutFilename)
		{
			PageLayout pageLayout = null;
			try
			{
				// init
				if (pubSite == null) { Publishing.GetPublishingSite(); }
				if (pubSite == null) { throw new Exception("PublishingSite passed is null and cannot get from SPContext"); }
				if (string.IsNullOrEmpty(pageLayoutFilename)) { throw new Exception("Page Layout Filename passed is null"); }
				pageLayoutFilename = pageLayoutFilename.ToLower();
				if (pageLayoutFilename.Contains("/")) { throw new Exception("Invalid page layout filename passed, cannot contain slash"); }
				if (pageLayoutFilename.Contains(" ")) { throw new Exception("Invalid page layout filename passed, cannot contain space"); }
				if (!pageLayoutFilename.Contains(".aspx")) { pageLayoutFilename += ".aspx"; }
				

				// 1.) get all existing layouts
				List<PageLayout> existingLayouts = GetPageLayouts(pubSite);
				if (existingLayouts == null || existingLayouts.Count == 0) { throw new Exception("No PageLayouts found in publishing site collection"); }

				// 2.) get page layout from collection
				foreach (PageLayout pl in existingLayouts)
				{
					if (pl.ListItem.File.Name.ToLower() == pageLayoutFilename)
					{
						pageLayout = pl;
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("rt6ujyjgfgg654545dF", ex, "filename: " + pageLayoutFilename);
				pageLayout = null;
			}
			return pageLayout;
		}

		/// <summary>
		/// Save multiple pages, failed pages added to a spearate collection
		/// </summary>
		/// <param name="pages"></param>
		/// <param name="comment"></param>
		/// <param name="checkInType"></param>
		/// <param name="isRemovePagesFailedToSave"></param>
		/// <param name="pagesFailedToSave"></param>
		public static void Save(List<PublishingPage> pages, string comment, bool isRemovePagesFailedToSave,
			ref List<PublishingPage> pagesFailedToSave)
		{
			try
			{
				// init
				if (pages == null) { throw new Exception("collection of pages to save passed is null"); }
				if (pages.Count == 0) { throw new Exception("Empty colelction of pages passed, nothing to save"); }
				if (pagesFailedToSave == null) { pagesFailedToSave = new List<PublishingPage>(); }


				foreach (PublishingPage page in pages)
				{
					string currentPage = page.Name;
					try
					{
						// try to save page
						if (!SaveAndPublish(page)) { throw new Exception("Failed to save page: " + currentPage); }
					}
					catch (Exception ex)
					{
						pagesFailedToSave.Add(page);
						Log.WriteError("r6ujhggfdfrd6t", ex);
					}
				}


				// remove documents that failed to save
				if (isRemovePagesFailedToSave && pagesFailedToSave != null && pagesFailedToSave.Count > 0)
				{
					for (int i = 0; i < pages.Count; i++)
					{
						bool isMatch = false;
						foreach (PublishingPage page in pagesFailedToSave)
						{
							if (pages[i] == page)
							{
								isMatch = true;
								break;
							}
						}
						if (isMatch)
						{
							pages.RemoveAt(i);
							i--;
						}
					}
				} // remove pages that failed to save
			}
			catch (Exception ex)
			{
				Log.WriteError("futhkGGgfgddr565v", ex);
			}
		}

		/// <summary>
		/// Save a publishing page
		/// </summary>
		/// <param name="page"></param>
		/// <param name="comment"></param>
		/// <returns></returns>
		public static bool Save(PublishingPage page, string comment)
		{
			bool isSuccess = false;
			try
			{
				List<PublishingPage> pagesToSave = new List<PublishingPage>(); pagesToSave.Add(page);
				List<PublishingPage> pagesFailedToSave = new List<PublishingPage>();
				Save(pagesToSave, comment, false, ref pagesFailedToSave);

				if (pagesFailedToSave.Count > 0) { isSuccess = false; }
				else { isSuccess = true; }
			}
			catch (Exception ex)
			{
				Log.WriteError("yo8gyfGGdrdrfrdty", ex);
				isSuccess = false;
			}
			return isSuccess;
		}
		/// <summary>
		/// Save publishing pages
		/// </summary>
		/// <param name="pages"></param>
		/// <param name="comment"></param>
		/// <returns></returns>
		public static bool Save(List<PublishingPage> pages, string comment)
		{
			bool isSuccess = false;
			try
			{
				List<PublishingPage> pagesFailedToSave = new List<PublishingPage>();
				Save(pages, comment, false, ref pagesFailedToSave);

				if (pagesFailedToSave.Count > 0) { isSuccess = false; }
				else { isSuccess = true; }

			}
			catch (Exception ex)
			{
				Log.WriteError("trdygffgdfrdtydthsder", ex);
				isSuccess = false;
			}
			return isSuccess;
		}


		/// <summary>
		/// Create a new publishing page
		/// </summary>
		/// <param name="pages"></param>
		/// <param name="filenameIncludingFolders"></param>
		/// <param name="layout"></param>
		/// <param name="isConvertSpacesToDashes">Converts spaces in filename into dashes, as SharePoint does by default</param>
		/// <param name="isConvertUnderscoresToDashes">Converts underscores into dashes</param>
		/// <returns></returns>
		public static PublishingPage CreatePage(PublishingPageCollection pages, string filenameIncludingFolders,
			PageLayout layout, bool isConvertSpacesToDashes, bool isConvertUnderscoresToDashes, bool isDupCheck)
		{
			PublishingPage page = null;
			try
			{
				// init
				if (pages == null) { pages = Publishing.GetPublishingWeb().GetPublishingPages(); }
				if (pages == null) { throw new Exception("PublishingPageCollection passed is null and can't get from SPContext"); }
				if (string.IsNullOrEmpty(filenameIncludingFolders)) { throw new Exception("Failename passed is null"); }
				if (filenameIncludingFolders == "/") { throw new Exception("Filename is only a foward slash, this is invalid"); }
				if (filenameIncludingFolders.Substring(filenameIncludingFolders.Length - 1, 1) == "/") { throw new Exception("Must pass filename"); }
				if (!filenameIncludingFolders.Contains(".")) { filenameIncludingFolders += ".aspx"; }
				if (layout == null) { throw new Exception("PageLayout passed is null"); }
				
				
				// format filename
				var filename = string.Empty;
				var folders = string.Empty;
				int foldersNumberChars = 0;
				if (filenameIncludingFolders.Contains("/"))
				{
					folders = filenameIncludingFolders.Substring(0, filenameIncludingFolders.LastIndexOf("/") + 1);
					filename = filenameIncludingFolders.Substring(filenameIncludingFolders.LastIndexOf("/") + 1);
					foldersNumberChars = folders.Length;
				}
				else
				{
					filename = filenameIncludingFolders;
				}
                filename = FileEx.FormatFilename(filename, foldersNumberChars, isConvertSpacesToDashes,
					isConvertUnderscoresToDashes, false);
				filenameIncludingFolders = folders + filename;

				// dup check
				if (isDupCheck) { throw new Exception("Dup check not enabled yet"); }

				// create new page
				page = pages.Add(filenameIncludingFolders, layout);
			}
			catch (Exception ex)
			{
				Log.WriteError("tdyujidydfdfrt5", ex, "filename (w/ folders): " + filenameIncludingFolders);
				page = null;
			}
			return page;
		}


		/// <summary>
		/// Create a page for the passed pages collection
		/// New page will be autoamtically added to collection and returned
		/// </summary>
		/// <param name="pages"></param>
		/// <param name="filenameIncludingFolders"></param>
		/// <param name="isDupCheck">If true, will ensure the page filename does not already exist</param>
		/// <param name="layout"></param>
		/// <returns></returns>
		public static PublishingPage CreatePage(PublishingPageCollection pages, string filenameIncludingFolders,
			PageLayout layout, bool isDupCheck)
		{
			return CreatePage(pages, filenameIncludingFolders, layout, true, true, isDupCheck);
		}


		public static PublishingPage CreatePage(PublishingWeb pWeb, string filenameIncludingFolders, 
			string pageContentTypeName, string pageLayoutName, bool isDupCheck)
		{
			try
			{
				// init
				if (pWeb == null) { pWeb = Publishing.GetPublishingWeb(); }
				if (pWeb == null) { throw new Exception("Publishing web passed is null and can't get it from SPContext"); }
				if (string.IsNullOrEmpty(pageContentTypeName)) { throw new Exception("Page Content Type Name passed is null"); }
				if (string.IsNullOrEmpty(pageLayoutName)) { throw new Exception("Page Layout Name passed is null"); }


				// get publishing site
				PublishingSite pSite = Publishing.GetPublishingSite(pWeb.Web.Site);
				if (pSite == null) { throw new Exception("Failed to get publishing site from passed publishing web"); }

				// get pages collection
				PublishingPageCollection pages = Page.GetPages(pWeb);
				if (pages == null) { throw new Exception("Failed to get publishing pages collection from publishing web: " + pWeb.Title); }

				// get SPContentType
				SPContentType contentType = Page.GetContentType(pSite, pageContentTypeName);
				if (contentType == null) { throw new Exception("Failed to get content type: " + pageContentTypeName 
					+ " in site: " + pSite.RootWeb.Url); }

				// get page layout
				PageLayout layout = Page.GetPageLayout(pSite, pageLayoutName, contentType);
				if (layout == null) { throw new Exception("Failed to get page layout: " + pageContentTypeName 
					+ " in site: " + pSite.RootWeb.Url); }

				return CreatePage(pages, filenameIncludingFolders, layout, isDupCheck); 
			}
			catch (Exception ex)
			{
				Log.WriteError("ti76ye5w4dsdsztez", ex);
				return null;
			}
		}

		/// <summary>
		/// Delete PublishingPages
		/// http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/bc5f4341-2274-4e95-b940-ca24aaea5713/
		/// </summary>
		/// <param name="pubWeb"></param>
		/// <param name="pagesToDelete"></param>
		/// <param name="isRemovePagesFailedToDelete"></param>
		/// <param name="pagesFailedToDelete"></param>
		public static void Delete(PublishingWeb pubWeb, List<PublishingPage> pagesToDelete,
			bool isRemovePagesFailedToDelete, ref List<PublishingPage> pagesFailedToDelete)
		{
			try
			{
				// init
				if (pubWeb == null) { pubWeb = Publishing.GetPublishingWeb(); }
				if (pubWeb == null) { throw new Exception("Failed to get PubloshingWeb from SPContext"); }
				if (pagesToDelete == null) { throw new Exception("Pages to delete collection passed is null"); }
				if (pagesFailedToDelete == null) { pagesFailedToDelete = new List<PublishingPage>(); }


				// make sure not deleting default page
				for (int i = 0; i < pagesToDelete.Count; i++)
				{
					if (pagesToDelete[i].Name == pubWeb.DefaultPage.Name)
					{
						// pagesFailedToDelete.Add(pagesToDelete[i]);
						pagesToDelete.RemoveAt(i);
						i--;
					}
				}

				// delete
				foreach (PublishingPage p in pagesToDelete)
				{
					string currentPage = p.Name;
					try
					{
						// try to delete page
						pubWeb.PagesList.Items.DeleteItemById(p.ListItem.ID);
					}
					catch (Exception ex)
					{
						pagesFailedToDelete.Add(p);
						Log.WriteError("ersy5dtrsrdds", "Failed to delete page: " + currentPage + ". Error: " + ex.Message + " \n\n\n" + ex.ToString());
					}
				}


				// remove documents that failed to save
				if (isRemovePagesFailedToDelete && pagesFailedToDelete != null && pagesFailedToDelete.Count > 0)
				{
					for (int i = 0; i < pagesToDelete.Count; i++)
					{
						bool isMatch = false;
						foreach (PublishingPage page in pagesFailedToDelete)
						{
							if (pagesToDelete[i] == page)
							{
								isMatch = true;
								break;
							}
						}
						if (isMatch)
						{
							pagesToDelete.RemoveAt(i);
							i--;
						}
					}
				} // remove pages that failed to delete
			}
			catch (Exception ex)
			{
				Log.WriteError("57iejtreheddd4d45", ex);
			}
		}

		/// <summary>
		/// Delete many pages
		/// </summary>
		/// <param name="pubWeb"></param>
		/// <param name="pagesToDelete"></param>
		/// <returns></returns>
		public static bool Delete(PublishingWeb pubWeb, List<PublishingPage> pagesToDelete)
		{
			bool isSuccess = false;
			try
			{
				List<PublishingPage> pagesFailedToDelete = new List<PublishingPage>();
				Delete(pubWeb, pagesToDelete, false, ref pagesFailedToDelete);

				if (pagesFailedToDelete.Count > 0) { isSuccess = false; }
				else { isSuccess = true; }

			}
			catch (Exception ex)
			{
				Log.WriteError("rtdugfxfdxhdssrtydxd", ex);
				isSuccess = false;
			}
			return isSuccess;
		}

		/// <summary>
		/// Delete passed collection of pages
		/// </summary>
		/// <param name="pubWeb"></param>
		/// <param name="pagesToDelete"></param>
		/// <returns></returns>
		public static bool Delete(PublishingWeb pubWeb, PublishingPageCollection pagesToDelete)
		{
			bool isSuccess = false;
			try
			{
				List<PublishingPage> pagesFailedToDelete = new List<PublishingPage>();
				var pagesToDeleteConverted = ConvertPublishingPageCollectionToGeneric(pagesToDelete);
				Delete(pubWeb, pagesToDeleteConverted, false, ref pagesFailedToDelete);

				if (pagesFailedToDelete.Count > 0) { isSuccess = false; }
				else { isSuccess = true; }
			}
			catch (Exception ex)
			{
				Log.WriteError("tryutythdsrsrddrgtgsrd", ex);
				isSuccess = false;
			}
			return isSuccess;
		}

		/// <summary>
		/// Delete page
		/// </summary>
		/// <param name="pubWeb"></param>
		/// <param name="pageToDelete"></param>
		/// <returns></returns>
		public static bool Delete(PublishingWeb pubWeb, PublishingPage pageToDelete)
		{
			bool isSuccess = false;
			try
			{
				var pagesToDelete = new List<PublishingPage>();
				if (pageToDelete != null) { pagesToDelete.Add(pageToDelete); }
				var pagesFailedToDelete = new List<PublishingPage>();
				Delete(pubWeb, pagesToDelete, false, ref pagesFailedToDelete);

				if (pagesFailedToDelete.Count > 0) { isSuccess = false; }
				else { isSuccess = true; }

			}
			catch (Exception ex)
			{
				Log.WriteError("rtdugfxfdxhdssrtydxd", ex);
				isSuccess = false;
			}
			return isSuccess;
		}

		/// <summary>
		/// Deletes all pages, save for the default page
		/// </summary>
		/// <param name="pubWeb"></param>
		public static void DeleteAll(PublishingWeb pubWeb)
		{
			try
			{
				if (pubWeb == null) { pubWeb = Publishing.GetPublishingWeb(); }
				if (pubWeb == null) { throw new Exception("Failed to get PublishingWeb from SPContext"); }

				// 1.) get all pages
				PublishingPageCollection _pagesToDelete = GetPages(pubWeb);
				List<PublishingPage> pagesToDelete = ConvertPublishingPageCollectionToGeneric(_pagesToDelete);

				// 2.) delete them
				Delete(pubWeb, pagesToDelete);
			}
			catch (Exception ex)
			{
				Log.WriteError("drttdudtsdd5fydufcxt", ex);
			}
		}


		public static List<PublishingPage> ConvertPublishingPageCollectionToGeneric(PublishingPageCollection pages)
		{
			List<PublishingPage> pagesConverted = null;
			if (pages != null)
			{
				pagesConverted = new List<PublishingPage>();
				foreach (PublishingPage p in pages)
				{
					pagesConverted.Add(p);
				}
			}
			return pagesConverted;
		}
		/// <summary>
		/// Change SharePoint page title from w/in a webpart
		/// Wither make the change this way, or via javascript
		/// </summary>
		/// <param name="p"></param>
		/// <param name="newTitle"></param>
		public static void ChangePageTitleFromWebPart(System.Web.UI.Page p, string newTitle)
		{
			try
			{
				if (!string.IsNullOrEmpty(newTitle))
				{
					// create literal control w/ new page title
					LiteralControl control = new LiteralControl();
					control.Text = newTitle;

					// call original
					ChangeMasterPageContentPlaceHolder(p, "PlaceHolderPageTitle", control, true);
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("dfgfdhgfgr6dr6dfxddts", ex, "new title: " + newTitle);
			}
		}

		public static void ChangeMasterPageContentPlaceHolder(System.Web.UI.Page p, string placeHolderId, LiteralControl literalToReplaceCurrentContent, bool isVisible)
		{
			try
			{
				if (!string.IsNullOrEmpty(placeHolderId) && p != null && p.Master != null)
				{
					// a.) get content placeHolder
					ContentPlaceHolder contentPlaceHolder = (ContentPlaceHolder)p.Master.FindControl(placeHolderId);
					if (contentPlaceHolder == null) { throw new Exception("Failed to get content placeholder"); }

					// b.) replace with new literalControl?
					if (literalToReplaceCurrentContent != null)
					{
						contentPlaceHolder.Controls.Clear();
						contentPlaceHolder.Controls.Add(literalToReplaceCurrentContent);
					}

					// c.) set visibility
					contentPlaceHolder.Visible = isVisible;
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("dsgfgfgdrrfdx", ex, "placeHolderId: " + placeHolderId);
			}
		}


		/// <summary>
		/// Convert page title to page filename
		/// DOES NOT dup check the filename!
		/// </summary>
		/// <param name="pageTitle">unencoded page title that will be converted into filename</param>
		/// <param name="numberCharAlreadyInUrl">Number of char already in url, minus domain name.</param>
		/// <returns></returns>
		public static string FormatPageFilename(string pageTitle, int numberCharAlreadyInUrl)
		{
			string o = null;
			try
			{
				// init
				if (string.IsNullOrEmpty(pageTitle)) { throw new Exception("No page title passed"); }
				o = pageTitle;


				// remove .aspx (just in case its the wrong case)
				if (o.Length > 5 && o.ToLower().Substring(o.Length - 5) == ".aspx")
				{
					o = o.Substring(o.Length - 5);
				}

				// append .aspx
				o += ".aspx";

				// format as valid filename (removes duplicate spaces, limits to 128 char in length, etc)
                o = FileEx.FormatFilename(o, numberCharAlreadyInUrl, true, true, false);
			}
			catch (Exception ex)
			{
				Log.WriteError("y6utjdfdhdftydrd", ex, "title passed to be formatted: " + pageTitle);
				o = null;
			}
			return o;
		}

		/// <summary>
		/// Convert page title to page filename
		/// DOES NOT dup check the filename!
		/// </summary>
		/// <param name="pageTitle">unencoded page title that will be converted into filename</param>
		/// <returns></returns>
		public static string FormatPageFilename(string pageTitle)
		{
			return FormatPageFilename(pageTitle, 0);
		}


		//public static bool DeleteAll(PublishingPageCollection pages, SPList pagesList, bool isDeletePermenatly)
		//{
		//    bool isSuccess = false;
		//    try
		//    {
		//        // init
		//        if (pages == null) { throw new Exception("PublishingPageCollection passed is null"); }
		//        if (pagesList == null) { throw new Exception("Pages list passed is null"); }


		//        // important, this will ALSO delete all existing recycle bin items!!!!!
		//        if (isDeletePermenatly) { pagesList.ParentWeb.Site.WebApplication.RecycleBinEnabled = false; }
		//        pagesList.ParentWeb.AllowUnsafeUpdates = true;

		//        string deleteCamlQuery = null;
		//        string camlStart = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>";
		//        string camlEnd = "</Batch>";

		//        string command = "<Method><SetList Scope=\"Request\">" + pagesList.ID +
		//            "</SetList><SetVar Name=\"ID\">{0}</SetVar><SetVar Name=\"Cmd\">Delete</SetVar></Method>";

		//        int numberItemsToBatchDelete = 0;
		//        for (int i = (pages.Count - 1); i > -1; i--)
		//        {
		//            // get items to delete
		//            deleteCamlQuery += string.Format(command, pages[i].ListItem.ID.ToString());
		//            numberItemsToBatchDelete++;

		//            // delete batch (every 100, or if last one)
		//            if (numberItemsToBatchDelete > 99 || i == 0)
		//            {
		//                deleteCamlQuery = camlStart + deleteCamlQuery + camlEnd;
		//                pagesList.ParentWeb.ProcessBatchData(deleteCamlQuery);
		//                // delete is successful, reset batch delete index and clear caml
		//                deleteCamlQuery = null;
		//                numberItemsToBatchDelete = 0;
		//            }
		//        }

		//        // assume success at this point
		//        isSuccess = true;
		//    }
		//    catch (Exception ex)
		//    {
		//        Log.WriteError("rtyhfgdgsffxhdrtg", ex);
		//        isSuccess = false;
		//    }
		//    finally
		//    {
		//        // re-enable recylce bin
		//        if (isDeletePermenatly) { pagesList.ParentWeb.Site.WebApplication.RecycleBinEnabled = true; }
		//        pagesList.ParentWeb.AllowUnsafeUpdates = false;
		//    }
		//    return isSuccess;
		//}


		public static bool ChangePageLayout(PublishingPage page, PageLayout newLayout)
		{
			bool isSuccess = true;
			try
			{
				// init
				if (page == null) { throw new Exception("Publishing Page passed is null"); }
				if (newLayout == null) { throw new Exception("Page Layout passed is null"); }
				var pubWeb = page.PublishingWeb;
				var oldLayout = page.Layout;


				// Confirm that the oldPageLayout and newPageLayout are compatible.
				if (oldLayout != null && oldLayout.AssociatedContentType.Id != newLayout.AssociatedContentType.Id)
				{
					throw new Exception("The page layouts must render the same type of content");
				}
				
				// check out
				if (IsCheckOutRequired(page)) { page.CheckOut(); }

				// apply change
				page.Layout = newLayout;

				// publish and save
				if (!SaveAndPublish(page)) { throw new Exception("Failed to publish and save page after applying new Page Layout"); }
            }
			catch (Exception ex)
			{
				Log.WriteError("7u6itk8uytdhrseagzdsdzdzf", ex);
				isSuccess = false;
			}
			return isSuccess;
		}

		/// <summary>
		/// Publish page, with checkin, publish, approval, then save
		/// </summary>
		/// <param name="page"></param>
		/// <param name="publishComment"></param>
		/// <param name="isCheckIn"></param>
		/// <param name="checkInComment"></param>
		/// <param name="isApprove"></param>
		/// <param name="approveComment"></param>
		/// <param name="isSave"></param>
		/// <returns></returns>
		public static bool Publish(PublishingPage page, string publishComment, string checkInComment, 
			bool isApprove, string approveComment, bool isSave, bool isSystemUpdate)
		{
			bool isSuccess = true;
			try
			{
				// init
				if (page == null) { throw new Exception("PublishingPage passed is null"); }
				if (!isSave && isSystemUpdate) { isSave = true; }


				// save
				if (isSave)
				{
					//SystemUpdate doesn't update the modified fields
					if (isSystemUpdate) { page.ListItem.SystemUpdate(); }
					else { page.Update(); }
				}

				// checkin
				if (IsCheckInRequired(page))
				{
					if (string.IsNullOrEmpty(checkInComment)) { checkInComment = string.Empty; }
					// get reference to SPFile to make sure it has the latest checkin state
					SPFile file = page.ListItem.File;
					file.CheckIn(checkInComment);
				}

				// publish
				if (page.ListItem.ParentList.EnableMinorVersions)
				{
					if (string.IsNullOrEmpty(publishComment)) { publishComment = string.Empty; }
					try { page.ListItem.File.Publish(publishComment); }
					catch (Exception ex) { Log.WriteError("ew56rytdrsdtrdtr", ex); }
				}

				// approve
				if (isApprove && page.ListItem.ParentList.EnableModeration)
				{
					if (string.IsNullOrEmpty(approveComment)) { approveComment = string.Empty; }
					try { page.ListItem.File.Approve(approveComment); }
					catch (Exception ex) { Log.WriteError("657gffddxzseaet", ex); }
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("erit8ydgrgsdfrdt", ex);
				isSuccess = false;
			}
			return isSuccess;
		}

		/// <summary>
		/// Publish PublishingPage, with automatic check-in and approval, then save 
		/// (no comments added)
		/// </summary>
		/// <param name="page"></param>
		/// <returns></returns>
		public static bool SaveAndPublish(PublishingPage page)
		{
			// call original
			return Publish(page, null, null, true, null, true, false);
		}

		/// <summary>
		/// Publish page, checkin, approve, then save using SystemUpdate()
		/// </summary>
		/// <param name="page"></param>
		/// <returns></returns>
		public static bool SystemSaveAndPublish(PublishingPage page)
		{
			// call original
			return Publish(page, null, null, true, null, true, true);
		}

		

		/// <summary>
		/// Does the passed page require check-out?
		/// </summary>
		/// <param name="page"></param>
		/// <returns></returns>
		public static bool IsCheckOutRequired(PublishingPage page)
		{
			bool isCheckOutRequired = false;
			if (page != null)
			{
				// get a new reference to SPFile to ensure proper checkin/out state
				// http://stackoverflow.com/questions/1460222/check-in-and-check-out-in-spfile-object
				SPFile file = page.ListItem.File;

				if (!List.IsCheckInOutRequired(page.ListItem.ParentList)) { isCheckOutRequired = false; }
				else
				{
					if (file.CheckOutType == SPFile.SPCheckOutType.None) { isCheckOutRequired = true; }
					else { isCheckOutRequired = false; }
				}
			}
			return isCheckOutRequired;
		}

		/// <summary>
		/// Does passed page require checkin?
		/// </summary>
		/// <param name="page"></param>
		/// <returns></returns>
		public static bool IsCheckInRequired(PublishingPage page)
		{
			bool isCheckInRequired = false;
			if (page != null)
			{
				// get a new reference to SPFile to ensure proper checkin/out state
				// http://stackoverflow.com/questions/1460222/check-in-and-check-out-in-spfile-object
				SPFile file = page.ListItem.File;
				if (file.CheckOutType != SPFile.SPCheckOutType.None)
				{
					isCheckInRequired = true;
				}
			}
			return isCheckInRequired;
		}

	} // end page class
}